
const { workerData, parentPort } = require('worker_threads');
const shelljs = require('shelljs');
const fs = require('fs');
const { Bundle } = require('../core/bundle');
const { BUNDLE_DIR, REPO_DIR, DEAFULT_README_NAMES, LICENSE_PATH_MAP, README_PATH_MAP, NONE_README, BUNDLE_REPO, NONE_LICENSE } = require('../constant');
const path = require("path");
const Git = require("../utils/git");
const { readJsonFile } = require('../utils');

const actionToCallback = {
  pack(cwd, { targetDir }) {
    const child = shelljs.exec('hpm pack', { async: true, cwd, silent: false })
    child.stdout.on("close", () => {
      shelljs.cp("-R", `${cwd}/*.tgz`, targetDir)
    })
  },
  publish(cwd) {
    shelljs.exec('hpm publish', { async: true, cwd })
  }
}

async function bundleEntry({ repoName, version, destPath, action, codeBranch }) {
  try {
    // 克隆仓库到REPO_DIR
    await new Git(repoName, REPO_DIR).clone(codeBranch)

    const shellCwd = path.resolve(REPO_DIR, repoName)
    let otherData = {
      version,
      segment: { destPath },
      envs: {},
      dirs: {},
      publishAs: "code-segment",
      license: "UNLICENSED"
    }
    const bundleJsonDir = path.resolve(shellCwd, "bundle.json")
    const readmeDir = path.resolve(shellCwd, "README.md")
    const licenseDir = path.resolve(shellCwd, "LICENSE")

    // 仓里暂无bundle.json文件，从bundleRepo拷贝与仓名相同的文件
    if(
      fs.existsSync(path.resolve(BUNDLE_REPO, `${repoName}.json`))
    ) {
      shelljs.cp("-R", path.resolve(BUNDLE_REPO, `${repoName}.json`), bundleJsonDir)
    }

    // 处理third_party仓库, 处理license文件以及描述
    const openSourceFile = path.resolve(shellCwd, "README.OpenSource")
    let sourceCwd = ""
    if (
      !fs.existsSync(licenseDir) &&
      fs.existsSync(openSourceFile) &&
      repoName.startsWith('third_party_')
    ) {
      const data = getInfoFromOpenSource(openSourceFile)
      if (data.description) {
        otherData.description = data.description
      }
      if (data.licensePath) {
        otherData.licensePath = data.licensePath
      }
    }
    // 如果已经定义路径，就以定义的路径为准，直接重写文件的字段,防止bundle.json中定义的路径就是错误的
    if (LICENSE_PATH_MAP[repoName]) {
      otherData.licensePath = LICENSE_PATH_MAP[repoName]
      otherData.require = true
    }

    if (otherData.licensePath) {
      dirName = path.dirname(otherData.licensePath)
      if (fs.existsSync(path.resolve(shellCwd, dirName))) {
        sourceCwd = path.resolve(shellCwd, dirName)
      }
    }

    // 处理找不到readme的仓库
    if (NONE_README.includes(repoName)) {
      const description = otherData.description || readJsonFile(bundleJsonDir).description
      fs.writeFileSync(path.resolve(shellCwd, "README.md"), description)
    }
	
	// 处理找不到LICENSE的仓库
    if (NONE_LICENSE.includes(repoName)) {
      const license_content = "UNLICENSED"
      fs.writeFileSync(path.resolve(shellCwd, "LICENSE"), license_content)
    }

    // 处理readme文件 先从根目录中查找、查找不到从LICENSE所在的目录查找
    if (!fs.existsSync(readmeDir) || repoName.startsWith('third_party_')) {
      let readmePath = { en: "" }
      if (!readmePath.en && README_PATH_MAP[repoName]) {
        readmePath = README_PATH_MAP[repoName]
        otherData.require = true
      }
      if(!readmePath.en) {
        readmePath = findReadme(shellCwd, shellCwd, DEAFULT_README_NAMES)
      }
      if (!readmePath.en && fs.existsSync(sourceCwd)) {
        readmePath = findReadme(sourceCwd, shellCwd, DEAFULT_README_NAMES.concat(["README.md"]))
      }
      if (readmePath.en) {
        if (!fs.existsSync(path.resolve(shellCwd, "README.md"))) {
          shelljs.cp("-R", path.resolve(shellCwd, readmePath.en), path.resolve(shellCwd, "README.md"))
        }
        otherData.readmePath = readmePath
      }
    }

    // 重写bundle.json部分字段
    if (fs.existsSync(bundleJsonDir)) {
      const bundle = new Bundle(bundleJsonDir, otherData)
      bundle.rewriteBundle()
      bundle.saveToFile()
    }

    // 删除.git .gitee 目录
    shelljs.rm("-rf", [path.resolve(shellCwd, ".git"), path.resolve(shellCwd, ".gitee")])

    // 检查仓库文件是否完整
    if (fs.existsSync(bundleJsonDir) && fs.existsSync(readmeDir)) {
      // 执行HPM命令
      const callback = actionToCallback[action]
      if (callback && typeof callback == "function") {
        callback(shellCwd, { targetDir: BUNDLE_DIR })
      }
    } else {
      const errlog = `${repoName} pack failed: missing bundle.json README.md or LICENSE`
      parentPort.postMessage(errlog)
    }
  } catch (err) {
    console.log(err);
    const errlog = `${repoName} pack failed: missing bundle.json README.md or LICENSE`
    parentPort.postMessage(errlog)
  }
}

function findReadme(sourceDir, absDir, fileName = DEAFULT_README_NAMES) {
  let readmePath = ""
  const dirs = fs.readdirSync(sourceDir, { withFileTypes: true, encoding: "utf-8" })
  for (let index = 0; index < dirs.length; index++) {
    const dir = dirs[index];
    if (dir.isFile()) {
      const readme = fileName.find(item => item === dir.name)
      if (readme) {
        readmePath = path.relative(absDir, path.resolve(sourceDir, readme))
        break
      }
    }
  }
  return { en: readmePath }
}

function getInfoFromOpenSource(dir) {
  try {
    const info = readJsonFile(dir);
    const licensePath = info[0]['License File']
    const description = info[0]['Description']
    return {
      licensePath,
      description
    }
  } catch(err) {
    return {
      licensePath: "",
      description: ""
    }
  }
}

bundleEntry(workerData)